package com.comiee.airwalker.enchantment

import com.comiee.airwalker.block.BlockAirGlass
import net.minecraft.enchantment.{Enchantment, EnchantmentHelper, EnumEnchantmentType}
import net.minecraft.inventory.EntityEquipmentSlot
import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent

import scala.collection.JavaConverters._
import scala.collection.mutable

/**
 * 虚空行者附魔。赋予玩家在空中行走的能力
 */
object EnchantmentAirWalker extends Enchantment(
  Enchantment.Rarity.COMMON, EnumEnchantmentType.ARMOR_FEET, List(EntityEquipmentSlot.FEET).toArray
) {

  private var tick = 0L
  private val blocks = mutable.Map[BlockPos, (Long, World)]()

  override def getMinEnchantability(enchantmentLevel: Int): Int = 15

  override def getMaxEnchantability(enchantmentLevel: Int): Int = {
    super.getMinEnchantability(enchantmentLevel) + 50
  }

  override def getMaxLevel: Int = 1

  override def canApplyTogether(ench: Enchantment): Boolean = {
    super.canApplyTogether(ench) && !Set("minecraft:depth_strider", "minecraft:frost_walker").contains(ench.getRegistryName.toString)
  }

  @SubscribeEvent
  def onPlayerTick(event: PlayerTickEvent): Unit = {
    tick += 1
    if (!event.player.world.isRemote) {
      if (!event.player.getArmorInventoryList.asScala.forall(
        itemStack => EnchantmentHelper.getEnchantmentLevel(EnchantmentAirWalker, itemStack) <= 0)
      ) {
        val world = event.player.world
        val pos = new BlockPos(event.player).down
        if (event.player.isSneaking) {
          if (world.getBlockState(pos).getBlock == BlockAirGlass) {
            world.setBlockToAir(pos)
          }
        }
        else {
          if (world.isAirBlock(pos)) {
            world.setBlockState(pos, BlockAirGlass.getDefaultState)
            blocks += pos -> (tick + 100, world)
          }
        }
      }
      blocks.foreach { case (pos, (t, world)) =>
        if (t <= tick && world.getBlockState(pos).getBlock == BlockAirGlass) {
          world.setBlockToAir(pos)
          blocks -= pos
        }
      }
    }
  }

  def destroy(): Unit = {
    blocks.foreach { case (pos, (_, world)) =>
      if (world.getBlockState(pos).getBlock == BlockAirGlass) {
        world.setBlockToAir(pos)
      }
    }
  }
}
